#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include "BlockQueue.hpp"
#include "Task.hpp"
/**************************************
 *         v1:消费者生产者模型交换数字
 * ***********************************/
// void *consumer(void *args)
// {
//     BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//     while(true){
//         int x;
//         bq->Pop(&x);
//         std::cout<<"--------------------------"<<std::endl;
//         std::cout<<"consum x="<<x<<" "<<bq->debug()<<std::endl;
//         sleep(0);
//     }
//     return nullptr;
// }

// void *productor(void *args)
// {
//     BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//     while (true)
//     {
//         int x = rand() % 100;
//         bq->Push(x);
//         std::cout<<"product x="<<x<<std::endl;

//     }
//     return nullptr;

// }

// int main()
// {
//     srand(time(nullptr) ^ getpid());
//     BlockQueue<int> *bq = new BlockQueue<int>();
//     pthread_t ctid, ptid;
//     pthread_create(&ctid, nullptr, consumer, bq);
//     pthread_create(&ptid, nullptr, productor, bq);

//     pthread_join(ctid, nullptr);
//     pthread_join(ptid, nullptr);

//     return 0;
// }

/**************************************
 *        v2:消费者生产者模型实现计算任务
 * ***********************************/
void *consumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    while (true)
    {
        Task t;
        bq->Pop(&t);
        t();
        std::cout << "pop:" << t.PrintResult() << std::endl;
    }
    return nullptr;
}

void *productor(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    while (true)
    {
        int x = rand() % 100;
        int y = rand() % 100;
        char op = opers[rand() % opers.size()];

        // 构建任务类型
        Task t(x, y, op);
        bq->Push(t);
        std::cout << "push:" << t.PrintTask() << std::endl;
        sleep(1);
    }
    return nullptr;
}

/**************
 *          v3单生产单消费
 * *************** */

// int main()
// {
//     srand(time(nullptr) ^ getpid());
//     BlockQueue<Task> *bq = new BlockQueue<Task>();
//     pthread_t ctid, ptid;
//     pthread_create(&ctid, nullptr, consumer, bq);
//     pthread_create(&ptid, nullptr, productor, bq);

//     pthread_join(ctid, nullptr);
//     pthread_join(ptid, nullptr);

//     return 0;
// }

/*********************
 *          v4多生产多消费
 * ******************* */

int main()
{
    srand(time(nullptr) ^ getpid());
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    pthread_t ctid1, ctid2, ctid3, ptid1, ptid2;
    pthread_create(&ctid1, nullptr, consumer, bq);
    pthread_create(&ctid2, nullptr, consumer, bq);
    pthread_create(&ctid3, nullptr, consumer, bq);
    pthread_create(&ptid1, nullptr, productor, bq);
    pthread_create(&ptid2, nullptr, productor, bq);

    pthread_join(ctid1, nullptr);
    pthread_join(ctid2, nullptr);
    pthread_join(ctid3, nullptr);
    pthread_join(ptid1, nullptr);
    pthread_join(ptid2, nullptr);

    return 0;
}